From 7922e6addb06de89cc73c64d30321aa6710e30ce Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Mon, 29 May 2017 21:33:30 +0200 Subject: Fixes problems with windows: - Changed cPlayer:OpenWindow to accept a ref, tolua adds a nil check - Close open lua window in destructor, to avoid dangling pointers --- src/Bindings/LuaWindow.cpp | 20 ++++++++++++++++++++ src/Bindings/LuaWindow.h | 3 ++- src/BlockEntities/BeaconEntity.cpp | 2 +- src/BlockEntities/BrewingstandEntity.cpp | 2 +- src/BlockEntities/ChestEntity.cpp | 2 +- src/BlockEntities/DropSpenserEntity.cpp | 2 +- src/BlockEntities/EnderChestEntity.cpp | 2 +- src/BlockEntities/FurnaceEntity.cpp | 2 +- src/BlockEntities/HopperEntity.cpp | 2 +- src/Blocks/BlockAnvil.h | 2 +- src/Blocks/BlockEnchantmentTable.h | 2 +- src/Blocks/BlockWorkbench.h | 2 +- src/Entities/Minecart.cpp | 2 +- src/Entities/Player.cpp | 10 +++++----- src/Entities/Player.h | 2 +- 15 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index 83463520c..fd714390e 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -4,8 +4,10 @@ #include "Globals.h" #include "LuaWindow.h" +#include "../Entities/Player.h" #include "../UI/SlotArea.h" #include "PluginLua.h" +#include "Root.h" #include "lua/src/lauxlib.h" // Needed for LUA_REFNIL @@ -51,6 +53,24 @@ cLuaWindow::~cLuaWindow() { m_Contents.RemoveListener(*this); + // Close open lua window from players, to avoid dangling pointers + class cPlayerCallback : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) + { + if (a_Player->GetWindow() == m_LuaWindow) + { + a_Player->CloseWindow(false); + } + return false; + } + cLuaWindow * m_LuaWindow; + public: + cPlayerCallback(cLuaWindow & a_LuaWindow) { m_LuaWindow = &a_LuaWindow; } + } PlayerCallback(*this); + + cRoot::Get()->ForEachPlayer(PlayerCallback); + // Must delete slot areas now, because they are referencing this->m_Contents and would try to access it in cWindow's // destructor, when the member is already gone. for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index 66efb2a32..f9db525fa 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -15,7 +15,8 @@ #include "../ItemGrid.h" - +class cPlayer; +typedef cItemCallback cPlayerListCallback; /** A window that has been created by a Lua plugin and is handled entirely by that plugin diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index c158db53b..f7728600a 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -297,7 +297,7 @@ bool cBeaconEntity::UsedBy(cPlayer * a_Player) // if (a_Player->GetWindow() != Window) // -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ... { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } return true; diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp index 27926c8df..464d175c9 100644 --- a/src/BlockEntities/BrewingstandEntity.cpp +++ b/src/BlockEntities/BrewingstandEntity.cpp @@ -65,7 +65,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index a47593108..9aeb50d5b 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -101,7 +101,7 @@ bool cChestEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index a7cea4256..e2e40148b 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -153,7 +153,7 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } return true; diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index 86c8ec463..d6ee9e016 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -66,7 +66,7 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } return true; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index b2ac093c0..bdbecfb79 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -69,7 +69,7 @@ bool cFurnaceEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index fbe073ada..c6cab90cd 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -95,7 +95,7 @@ bool cHopperEntity::UsedBy(cPlayer * a_Player) { if (a_Player->GetWindow() != Window) { - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); } } diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 28718e316..19f6b9bca 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -27,7 +27,7 @@ public: virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ); - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); return true; } diff --git a/src/Blocks/BlockEnchantmentTable.h b/src/Blocks/BlockEnchantmentTable.h index e8ce734b3..365c4004d 100644 --- a/src/Blocks/BlockEnchantmentTable.h +++ b/src/Blocks/BlockEnchantmentTable.h @@ -21,7 +21,7 @@ public: virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ); - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); return true; } diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h index eb75647ff..f35d5aa35 100644 --- a/src/Blocks/BlockWorkbench.h +++ b/src/Blocks/BlockWorkbench.h @@ -21,7 +21,7 @@ public: virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); - a_Player->OpenWindow(Window); + a_Player->OpenWindow(*Window); return true; } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index b8e8e9f29..7f32dc910 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1222,7 +1222,7 @@ void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) { if (a_Player.GetWindow() != Window) { - a_Player.OpenWindow(Window); + a_Player.OpenWindow(*Window); } } } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c0a078bcb..b11c07a0b 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1310,15 +1310,15 @@ cTeam * cPlayer::UpdateTeam(void) -void cPlayer::OpenWindow(cWindow * a_Window) +void cPlayer::OpenWindow(cWindow & a_Window) { - if (a_Window != m_CurrentWindow) + if (&a_Window != m_CurrentWindow) { CloseWindow(false); } - a_Window->OpenedByPlayer(*this); - m_CurrentWindow = a_Window; - a_Window->SendWholeWindow(*GetClientHandle()); + a_Window.OpenedByPlayer(*this); + m_CurrentWindow = &a_Window; + a_Window.SendWholeWindow(*GetClientHandle()); } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index d25432e9f..dc8f07823 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -229,7 +229,7 @@ public: // tolua_begin /** Opens the specified window; closes the current one first using CloseWindow() */ - void OpenWindow(cWindow * a_Window); + void OpenWindow(cWindow & a_Window); /** Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true */ void CloseWindow(bool a_CanRefuse = true); -- cgit v1.2.3